using System;
using System.Collections.Generic;
using System.Text;

namespace SilverlightBlowfish
{
    class PublicFuntion
    {
        static char[] HEXTAB = {
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
            'a', 'b', 'c', 'd', 'e', 'f'
        };

        internal  static long ByteArrayToLong(byte[] buffer, int nStartIndex)
        {
            return (long)buffer[nStartIndex] << 56 |
                ((long)buffer[nStartIndex + 1] & 255L) << 48 |
                ((long)buffer[nStartIndex + 2] & 255L) << 40 |
                ((long)buffer[nStartIndex + 3] & 255L) << 32 |
                ((long)buffer[nStartIndex + 4] & 255L) << 24 |
                ((long)buffer[nStartIndex + 5] & 255L) << 16 |
                ((long)buffer[nStartIndex + 6] & 255L) << 8 |
                (long)buffer[nStartIndex + 7] & 255L;
        }
        internal  static void LongToByteArray(long lValue, byte[] buffer, int nStartIndex)
        {
            buffer[nStartIndex] = (byte)(int)(lValue >> 56);
            buffer[nStartIndex + 1] = (byte)(int)(lValue >> 48 & 255L);
            buffer[nStartIndex + 2] = (byte)(int)(lValue >> 40 & 255L);
            buffer[nStartIndex + 3] = (byte)(int)(lValue >> 32 & 255L);
            buffer[nStartIndex + 4] = (byte)(int)(lValue >> 24 & 255L);
            buffer[nStartIndex + 5] = (byte)(int)(lValue >> 16 & 255L);
            buffer[nStartIndex + 6] = (byte)(int)(lValue >> 8 & 255L);
            buffer[nStartIndex + 7] = (byte)(int)lValue;
        }

        internal  static long IntArrayToLong(int[] buffer, int nStartIndex)
        {
            return (long)buffer[nStartIndex] << 32 |
                (long)buffer[nStartIndex + 1] & 0xffffffffL;
        }
        internal  static void LongToIntArray(long lValue, int[] buffer, int nStartIndex)
        {
            buffer[nStartIndex] = (int)(lValue >> 32);
            buffer[nStartIndex + 1] = (int)lValue;
        }

        internal  static long MakeLong(int nLo, int nHi)
        {
            return (long)nHi << 32 |
                (long)nLo & 0xffffffffL;
        }
        internal  static int LongLo32(long lVal)
        {
            return (int)lVal;
        }
        internal  static int LongHi32(long lVal)
        {
            return (int)(lVal >> 32);
        }

        internal  static String BytesToBinHex(byte[] data, int nStartPos, int nNumOfBytes)
        {
            StringBuilder sbud = new StringBuilder();
            for (int nI = 0; nI < nNumOfBytes; nI++)
            {
                sbud.Append(HEXTAB[data[nI + nStartPos] >> 4 & 0x0f]);
                sbud.Append(HEXTAB[data[nI + nStartPos] & 0x0f]);
            }
            return sbud.ToString();
        }
        internal  static int BinHexToBytes(String sBinHex, byte[] data, int nSrcPos, int nDstPos, int nNumOfBytes)
        {
            int nStrLen = sBinHex.Length;
            int nAvailBytes = nStrLen - nSrcPos >> 1;
            if (nNumOfBytes > nAvailBytes)
            {
                nNumOfBytes = nAvailBytes;
            }
            int nOutputCapacity = data.Length - nDstPos;
            if (nNumOfBytes > nOutputCapacity)
            {
                nNumOfBytes = nOutputCapacity;
            }
            int nResult = 0;
            for (int nI = 0; nI < nNumOfBytes; nI++)
            {
                byte bActByte = 0;
                bool blConvertOK = true;
                for (int nJ = 0; nJ < 2; nJ++)
                {
                    bActByte <<= 4;
                    char cActChar = sBinHex[nSrcPos++];
                    if (cActChar >= 'a' && cActChar <= 'f')
                    {
                        bActByte |= (byte)(cActChar - 97 + 10);
                        continue;
                    }
                    if (cActChar >= '0' && cActChar <= '9')
                    {
                        bActByte |= (byte)(cActChar - 48);
                    }
                    else
                    {
                        blConvertOK = false;
                    }
                }
                if (blConvertOK)
                {
                    data[nDstPos++] = bActByte;
                    nResult++;
                }
            }
            return nResult;
        }

        internal  static String ByteArrayToUNCString(byte[] data, int nStartPos, int nNumOfBytes)
        {
            nNumOfBytes &= -2;
            int nAvailCapacity = data.Length - nStartPos;
            if (nNumOfBytes > nAvailCapacity)
            {
                nNumOfBytes = nAvailCapacity;
            }
            StringBuilder sbud = new StringBuilder();
            for (; nNumOfBytes > 0; nNumOfBytes -= 2)
            {
                sbud.Append((char)(data[nStartPos] << 8 | data[nStartPos + 1] & 0xff));
                nStartPos += 2;
            }
            return sbud.ToString();
        }
    }
}
